package com.mcxx.modules.common.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.mcxx.modules.common.service.CheckStartService;
import com.mcxx.modules.miniSalvation.check.dto.*;
import com.mcxx.modules.miniSalvation.check.entity.CheckEntity;
import com.mcxx.modules.miniSalvation.check.service.read.CheckReadService;
import com.mcxx.modules.miniSalvation.check.service.write.CheckWriteService;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMemberHistoryReadService;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMemberReadService;
import com.mcxx.modules.miniSalvation.family.service.read.FamilySupportReadService;
import com.mcxx.modules.miniSalvation.order.dto.CheckDTO;
import com.mcxx.modules.miniSalvation.order.service.read.OrderCertReadService;
import com.mcxx.modules.miniSalvation.order.service.read.OrderReadService;
import com.mcxx.modules.temporary.family.service.read.TmpFamilyMemberReadService;
import com.mcxx.modules.temporary.order.service.read.TmpOrderCertReadService;
import com.mcxx.modules.temporary.order.service.read.TmpOrderReadService;
import com.mcxx.util.Constant;
import com.mcxx.util.HttpServiceUtil;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
@TaTransactional
public class CheckStartServiceImpl implements CheckStartService {
    private final static Logger logger = LoggerFactory.getLogger(CheckStartServiceImpl.class);
    @Autowired
    private FamilyMemberReadService familyMemberReadService;
    @Autowired
    private FamilyMemberHistoryReadService familyMemberHistoryReadService;
    @Autowired
    private OrderCertReadService orderCertReadService;
    @Autowired
    private CheckWriteService checkWriteService;
    @Autowired
    private OrderReadService orderReadService;
    @Autowired
    private TmpOrderReadService tmpOrderReadService;
    @Autowired
    private TmpFamilyMemberReadService tmpFamilyMemberReadService;
    @Autowired
    private TmpOrderCertReadService tmpOrderCertReadService;
    @Autowired
    private FamilySupportReadService familySupportReadService;
    @Autowired
    private CheckReadService checkReadService;

    @Value("${yinhai.check.service-url:http://10.22.197.101:10000/engine/rest/}")
    private String serviceUrl;

    @Value("${yinhai.check.username:user}")
    private String userName;

    @Value("${yinhai.check.password:pas}")
    private String password;

    @Value("${yinhai.check.flag-wthd:mzhd_jzwthd}")
    private String flagWthd;

    @Value("${yinhai.data-sync.access-key:hnsocialrelief}")
    private String accessKey;



    @Override
    public String startCheck(String bizContent,String businessCode,String areaCode){
        List<CheckDTO> checkIdList =  JSONArray.parseArray(bizContent,CheckDTO.class);
        String resMsg = "";

        Map<String,String> header = new HashMap<>();
        header.put("username",userName);
        header.put("password",password);
        header.put("request",new Date().toString());
        header.put("service",flagWthd);
        String checkUrl = serviceUrl+flagWthd;


        if(Constant.BusinessCode.DIBAO.equals(businessCode)){


            List<CheckDTO> cityDto = checkIdList.stream().filter(checkDTO -> (Constant.BusinessStandType.CITY_DIBAO).equals(checkDTO.getStandType())).collect(Collectors.toList());
            if(cityDto!=null&&cityDto.size()>0){
                CheckRequestDTO cityCheckDTO = this.queryMiniCheckInfo(cityDto,areaCode);
                String cityMsg =  this.sendHttp(cityCheckDTO,header,checkUrl,"1.0");
                resMsg = resMsg+cityMsg;
            }

            List<CheckDTO> countryDto = checkIdList.stream().filter(checkDTO -> (Constant.BusinessStandType.COUNTY_DIBAO).equals(checkDTO.getStandType())).collect(Collectors.toList());
            if(countryDto!=null&&countryDto.size()>0){
                CheckRequestDTO countryChekDto = this.queryMiniCheckInfo(countryDto,areaCode);
                String countryMsg = this.sendHttp(countryChekDto,header,checkUrl,"1.0");

                if(!countryMsg.equals(resMsg)){
                    resMsg = resMsg+countryMsg;
                }
            }
        }else if(Constant.BusinessCode.TEKUN.equals(businessCode)){

            List<CheckDTO> cityDto = checkIdList.stream().filter(checkDTO -> (Constant.BusinessStandType.CITY_TEKUN).equals(checkDTO.getStandType())).collect(Collectors.toList());
            if(cityDto!=null&&cityDto.size()>0){
                CheckRequestDTO cityCheckDTO = this.queryMiniCheckInfo(cityDto,areaCode);
                String cityMsg = this.sendHttp(cityCheckDTO,header,checkUrl,"1.0");
                resMsg = resMsg+cityMsg;
            }

            List<CheckDTO> countryDto = checkIdList.stream().filter(checkDTO -> (Constant.BusinessStandType.COUNTY_TEKUN).equals(checkDTO.getStandType())).collect(Collectors.toList());
            if(countryDto!=null&&countryDto.size()>0){
                CheckRequestDTO countryChekDto = this.queryMiniCheckInfo(countryDto,areaCode);
                String countryMsg =  this.sendHttp(countryChekDto,header,checkUrl,"1.0");

                if(!countryMsg.equals(resMsg)){
                    resMsg = resMsg+countryMsg;
                }
            }
        }else{

            CheckRequestDTO tmpCheckDTO= this.queryTmpCheckInfo(checkIdList,areaCode);
            resMsg = this.sendHttp(tmpCheckDTO,header,checkUrl,"1.0");
        }
     return  resMsg;
    }

    public CheckRequestDTO queryMiniCheckInfo(List<CheckDTO> checkDTOList,String areaCode){
        CheckRequestDTO dto = new CheckRequestDTO();

        boolean supportFlag  = true;
        if("0".equals(checkDTOList.get(0).getFamilySupport())){
            supportFlag = false;
        }

        dto.setBbex0001(checkDTOList.get(0).getCheckBatchNo());
        String checkType = checkDTOList.get(0).getCheckType();

        if(Constant.CheckType.BATCH_RECHECK.equals(checkType)){

            dto.setBbee0002(Constant.CheckType.RECHECK);
        }else{

            dto.setBbee0002(checkDTOList.get(0).getCheckType());
        }

        dto.setBxcp0013(areaCode);

        dto.setBbee0026(checkDTOList.get(0).getStandType());

        dto.setBbee0023("");

        int num = 0;
        List<String> orderIds = checkDTOList.stream().map(checkDTO -> checkDTO.getOrderId()).collect(Collectors.toList());
        List<CheckFamilyDTO> checkFamilyDTOS = null;

        checkFamilyDTOS = null;
        if(Constant.CheckType.BATCH_RECHECK.equals(checkType)){
            checkFamilyDTOS = orderReadService.getCheckInfoByHistory(orderIds);
        }else {
            checkFamilyDTOS = orderReadService.getCheckInfo(orderIds);
        }

        for(CheckFamilyDTO checkFamilyDTO:checkFamilyDTOS){
            String orderId = checkFamilyDTO.getBbee0002().split(",")[0];
            String familyId = checkFamilyDTO.getBbee0002().split(",")[1];

            String checkId = checkDTOList.stream().filter(o -> o.getOrderId().equals(orderId)).map(o -> o.getCheckId()).findFirst().get();

            checkFamilyDTO.setBbee0002(checkId);

            List<CheckMemberDTO> checkMemberDTOS = null;
            if(Constant.CheckType.BATCH_RECHECK.equals(checkType)){
                checkMemberDTOS =  familyMemberHistoryReadService.selectMemberListInfo(orderId,familyId);
            }else {
                checkMemberDTOS =  familyMemberReadService.selectMemberListInfo(familyId);
            }
            num += checkMemberDTOS.size();
            int i=0;
            for(CheckMemberDTO checkMemberDTO:checkMemberDTOS){

                List<CheckFileDTO> fileInfos = orderCertReadService.getFileByMemberId(checkMemberDTO.getBbee0001(),orderId);

                if(Constant.DomesticRelation.ONESELF.equals(checkMemberDTO.getBxcp0025())){
                    List<CheckFileDTO> authorFile = orderCertReadService.getAuthorFile(Constant.FileType.CHECK_EMPOWER,orderId);
                    if(CollectionUtils.isNotEmpty(authorFile)){
                        fileInfos.addAll(authorFile);
                    }
                }
                checkMemberDTO.setFjclxx(fileInfos);

                checkMemberDTO.setBbee0001(checkMemberDTO.getBbee0001()+checkId);
            }
            if(supportFlag){

                List<CheckMemberDTO> supportList = familySupportReadService.selectSupportListInfo(familyId);
                if(CollectionUtils.isNotEmpty(supportList)){
                    num += supportList.size();

                    for(CheckMemberDTO support:supportList){

                        List<CheckFileDTO> authorFile = orderCertReadService.getFileBySupportId(Constant.CheckFileType.AUTHOR_FILE,Constant.FileType.SUPPORT_CHECK_EMPOWER, orderId,support.getBbee0001());

                        List<CheckFileDTO> fileInfos = orderCertReadService.getFileBySupportId(Constant.CheckFileType.IDCARD_FILE,Constant.FileType.SUPPORT_IDCARD,orderId,support.getBbee0001());

                        if(CollectionUtils.isNotEmpty(authorFile)){
                            fileInfos.addAll(authorFile);
                        }
                        support.setFjclxx(fileInfos);
                        support.setBbee0001(support.getBbee0001()+checkId);
                    }

                    checkMemberDTOS.addAll(supportList);
                }
            }

            checkFamilyDTO.setJtcyxx(checkMemberDTOS);

            checkFamilyDTO.setBbee0001(checkFamilyDTO.getBbee0001()+checkId);
        }

        dto.setBbee0006(String.valueOf(num));
        dto.setHdjtxx(checkFamilyDTOS);
        return dto;
    }

    public CheckRequestDTO queryTmpCheckInfo(List<CheckDTO> checkDTOList,String areaCode){
        CheckRequestDTO dto = new CheckRequestDTO();

        dto.setBbex0001(checkDTOList.get(0).getCheckBatchNo());

        dto.setBbee0002(checkDTOList.get(0).getCheckType());

        dto.setBxcp0013(areaCode);

        dto.setBbee0026(Constant.BusinessStandType.LINGSHI);

        dto.setBbee0023("");

        int num = 0;
        List<String> orderIds = checkDTOList.stream().map(checkDTO -> checkDTO.getOrderId()).collect(Collectors.toList());
        List<CheckFamilyDTO> checkFamilyDTOS = null;

        checkFamilyDTOS = tmpOrderReadService.getCheckInfo(orderIds);

        for(CheckFamilyDTO checkFamilyDTO:checkFamilyDTOS){

            String checkId = checkDTOList.stream().filter(o -> o.getOrderId().equals(checkFamilyDTO.getBbee0002())).map(o -> o.getCheckId()).findFirst().get();
            String memberId = checkFamilyDTO.getBbee0001();
            String orderId = checkFamilyDTO.getBbee0002();
            checkFamilyDTO.setBbee0002(checkId);

            List<CheckMemberDTO> checkMemberDTOS = tmpFamilyMemberReadService.selectMemberListInfo(memberId);
            num += checkMemberDTOS.size();
            for(CheckMemberDTO checkMemberDTO:checkMemberDTOS){
                List<CheckFileDTO> fileInfos = tmpOrderCertReadService.getFileByMemberId(checkMemberDTO.getBbee0001(),orderId);

                if(Constant.DomesticRelation.ONESELF.equals(checkMemberDTO.getBxcp0025())){
                    List<CheckFileDTO> authorFile = tmpOrderCertReadService.getAuthorFile(Constant.FileType.CHECK_EMPOWER,orderId);
                    if(CollectionUtils.isNotEmpty(authorFile)){
                        fileInfos.addAll(authorFile);
                    }
                }
                checkMemberDTO.setFjclxx(fileInfos);
                checkMemberDTO.setField_29("");
                checkMemberDTO.setField_30("");
                checkMemberDTO.setBbee0001(checkMemberDTO.getBbee0001()+checkId);
            }
            checkFamilyDTO.setJtcyxx(checkMemberDTOS);

            checkFamilyDTO.setBbee0001(checkFamilyDTO.getBbee0001()+checkId);
        }

        dto.setBbee0006(String.valueOf(num));
        dto.setHdjtxx(checkFamilyDTOS);
        return dto;
    }


    public String sendHttp(CheckRequestDTO dto,Map<String,String> header,String url,String version){

        String batchNo = dto.getBbex0001();
        String res = null;
        Gson gson = new Gson();
        String dtoString = gson.toJson(dto);

        String idCards = checkReadService.selectIdcardByBatchNo(batchNo);
        logger.info("核对委托请求报文req：{}",dtoString);
        try {
            res = HttpServiceUtil.callServiceWithNativeHttp(accessKey,url,dtoString,version);
        } catch (Exception e) {
            logger.error("发起核对请求异常"+e);

            checkWriteService.updateCheckStateByBatchNo(dto.getBbex0001(),null,"核对接口异常",Constant.CheckState.CHECK_EXCEPTION);
            return "户主身份证为【"+idCards+"】的家庭发起核对失败;";
        }
        logger.info("核对委托响应res:{}",res);
        JSONObject resJSON = null;
        try {
            resJSON = JSONObject.parseObject(res);
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("发起核对响应转换json异常");

            checkWriteService.updateCheckStateByBatchNo(dto.getBbex0001(),null,"核对响应数据异常",Constant.CheckState.CHECK_EXCEPTION);
            return "户主身份证为【"+idCards+"】的家庭发起核对失败;";
        }

        if(resJSON==null||resJSON.containsKey("code")==false){
            checkWriteService.updateCheckStateByBatchNo(dto.getBbex0001(),null,"核对服务响应码为空",Constant.CheckState.CHECK_EXCEPTION);
            logger.info("银海服务集成响应码为空");
            return "户主身份证为【"+idCards+"】的家庭发起核对失败;";
        }

        String resCode = resJSON.getString("code");
        logger.info("银海服务集成响应码：{}",resCode);
        if("1".equals(resCode)){

            String checkCode = resJSON.getJSONObject("biz_data").getString("code");
            logger.info("核对处理响应码{}",checkCode);
            if(Constant.CheckResCode.WTHD_SUCCESS.equals(checkCode)){

                checkWriteService.updateCheckStateByBatchNo(batchNo, null,null,Constant.CheckState.PROVINCE_RECEIVE);
                return "发起核对成功";
            }else{
                if(Constant.CheckResCode.VALIDATE_ERROR.equals(checkCode)){

                    checkWriteService.updateCheckStateByBatchNo(batchNo,null,"核对批次数据解析异常",Constant.CheckState.CHECK_EXCEPTION);
                    return "户主身份证为【"+idCards+"】的家庭发起核对失败,批次数据解析异常;";
                }else if(Constant.CheckResCode.BATCH_DATA_ERROR.equals(checkCode)){

                    checkWriteService.updateCheckStateByBatchNo(batchNo,null,"批次数据校验异常",Constant.CheckState.CHECK_EXCEPTION);
                    return "户主身份证为【"+idCards+"】的家庭发起核对失败,批次数据校验异常;";
                } else if(Constant.CheckResCode.OBJECT_ERROR.equals(checkCode)){

                    StringBuffer sb = new StringBuffer();

                    JSONObject msgJSON =  resJSON.getJSONObject("biz_data").getJSONObject("msg");

                    List<String> errorCheckIds = new ArrayList<>();

                    if(msgJSON.containsKey("jtError")){
                         JSONArray jtErrorArray = msgJSON.getJSONArray("jtError");
                         for(int i=0;i<jtErrorArray.size();i++){
                             JSONObject objectError = jtErrorArray.getJSONObject(i);
                             String errorCheckId = objectError.getString("bbee0002");
                             errorCheckIds.add(errorCheckId);
                             String errorMsg = "身份证明材料附件或授权声明材料附件信息异常;";
                             if(objectError.containsKey("jtcyError")){
                                 JSONObject jtcyErrorJson = objectError.getJSONArray("jtcyError").getJSONObject(0);
                                 errorMsg = jtcyErrorJson.getString("msg");
                             }

                             CheckEntity entity = new CheckEntity();
                             entity.setCheckId(errorCheckId);
                             entity.setExceptionMsg(errorMsg);
                             entity.setCheckState(Constant.CheckState.CHECK_EXCEPTION);
                             checkWriteService.updateCheckByCheckId(entity);
                         }
                        String errorIdCard = checkReadService.selectIdcardByCheckId(errorCheckIds);
                        sb.append("户主身份证为【"+errorIdCard+"】的家庭对象数据校验异常;");
                    }


                    List<String> repeatCheckIds = new ArrayList<>();
                    if(msgJSON.containsKey("jtRepeat")){
                        JSONArray jtErrorArray = msgJSON.getJSONArray("jtRepeat");
                        for(int i=0;i<jtErrorArray.size();i++){
                            JSONObject objectError = jtErrorArray.getJSONObject(i);
                            String repeatCheckId = objectError.getString("bbee0002");
                            errorCheckIds.add(repeatCheckId);
                            repeatCheckIds.add(repeatCheckId);
                            String errorMsg = "委托对象重复发起";

                            CheckEntity entity = new CheckEntity();
                            entity.setCheckId(repeatCheckId);
                            entity.setExceptionMsg(errorMsg);
                            entity.setCheckState(Constant.CheckState.CHECK_EXCEPTION);
                            checkWriteService.updateCheckByCheckId(entity);
                        }
                        String errorIdCard = checkReadService.selectIdcardByCheckId(repeatCheckIds);
                        sb.append("户主身份证为【"+errorIdCard+"】的家庭委托对象重复发起;");
                    }

                    checkWriteService.updateCheckStateByBatchNo(batchNo, errorCheckIds,null,Constant.CheckState.PROVINCE_RECEIVE);
                    return sb.toString();
                }else{

                    checkWriteService.updateCheckStateByBatchNo(batchNo,null,"核对响应码"+checkCode,Constant.CheckState.CHECK_EXCEPTION);
                    return "户主身份证为【"+idCards+"】的家庭发起核对失败;";
                }
            }
        }else{

            String errorMsg = resJSON.containsKey("msg")?resJSON.getString("msg"):"";
            checkWriteService.updateCheckStateByBatchNo(batchNo,null,"核对服务响应码"+resCode+"-"+errorMsg,Constant.CheckState.CHECK_EXCEPTION);
            return "户主身份证为【"+idCards+"】的家庭发起核对失败;";
        }
    }
}
